# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import datetime

from django.shortcuts import render
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django.views.generic.base import View
from django.contrib.auth.hashers import make_password  # 对明文加密

from users.models import UserProfile, EmailVerifyRecord
from users.forms import RegisterForm, ForgetPwdForm, ModifyPwdForm, LoginForm
from utils.email_Send import send_email, is_expired

# Create your views here.


class CustomBackend(ModelBackend):
	"""自定义auth登录方法"""
	def authenticate(self, username=None, password=None, **kwargs):
		try:
			user = UserProfile.objects.get(Q(username=username)|Q(email=username))  # `Q`间用`|`表示or,用`,`表示and
			if user.check_password(password):
				return user

		except Exception as e:
			return None


class RegisterView(View):
	def get(self, request):
		context = {}

		register_form = RegisterForm()  # 用于生成html字段代码（不验证字段，则不需要传字段参数）
		context['register_form'] = register_form
		return render(request, 'users/register.html', context=context)

	def post(self, request):
		context = {}

		register_form = RegisterForm(request.POST)
		context['register_form'] = register_form
		if register_form.is_valid():
			# 获取表单数据
			user_name = request.POST.get('email', '')
			pass_word = request.POST.get('password', '')
			if UserProfile.objects.filter(email=user_name).count() == 0:  # 邮箱未注册
				# 将数据存储
				user_profile = UserProfile()  # 实例化model
				user_profile.email = user_name
				user_profile.is_active = False  # 注册时,置于未激活状态
				user_profile.username = user_name
				user_profile.password = make_password(pass_word, salt=user_name)  # 对明文加密
				user_profile.save()  # 存储
				send_email(user_name, 'register')  # 发送注册激活链接
				return render(request, 'users/register_success.html')

			else:  # 邮箱已注册
				context['msg'] = '该邮箱已注册'
				return render(request, 'users/register.html', context=context)

		else:
			return render(request, 'users/register.html', context=context)


class ActiveUserView(View):
	def get(self, request, active_code):
		context = {}

		# 查询url中的code是否存在于数据库（发送邮件前会保存邮件内到数据库）
		all_records = EmailVerifyRecord.objects.filter(code=active_code)
		if all_records:  # 如果存在，则根据code查询email, 再将该记录的`is_active`值变为`True`，即激活状态
			for record in all_records:
				if record.expire_status == 1:  # 若不过期
					email = record.email
					code = record.code
					obj_user = UserProfile.objects.get(email=email)
					obj_user.is_active = True  # 用户置于激活状态
					obj_user.save()
					obj_email = EmailVerifyRecord.objects.get(code=code)
					obj_email.expire_status = 0  # 验证链接置于过期状态
					obj_email.save()
				return render(request, 'users/actived.html')

		else:
			return render(request, 'users/url_failed.html')


class ForgetPwdView(View):
	def get(self, request):
		context = {}

		forgetpwd_form = ForgetPwdForm()
		context['forgetpwd_form'] = forgetpwd_form
		return render(request, 'users/forgetpwd.html', context=context)

	def post(self, request):
		context = {}

		forgetpwd_form = ForgetPwdForm(request.POST)
		context['forgetpwd_form'] = forgetpwd_form
		if forgetpwd_form.is_valid():
			user_name = request.POST.get('email', '')
			if UserProfile.objects.filter(email=user_name).count() == 0:  # 邮箱未注册
				context['msg'] = '该邮箱未注册'
				return render(request, 'users/forgetpwd.html', context=context)
			
			else:
				send_email(user_name, 'forgetpwd')
				return render(request, 'users/send_success.html', context=context)

		else:
			return render(request, 'users/forgetpwd.html', context=context)


class ResetPwdView(View):
	def get(self, request, reset_code):
		context = {}

		# 查询url中的code是否存在于数据库（发送邮件前会保存邮件内到数据库）
		all_records = EmailVerifyRecord.objects.filter(code=reset_code)
		if all_records:  # 如果存在，则返回重置密码页面
			for record in all_records:
				email = record.email
				code = record.code  # 取出email, 传给html--给post用
				obj_email = EmailVerifyRecord.objects.get(code=code)
				expire_time = record.send_time + datetime.timedelta(days=1)  # 过期时间
				# print expire_time
				if is_expired(expire_time):  # 若过期
					obj_email.expire_status = 0  # 验证链接置于过期状态

				if obj_email.expire_status == 1:  # 若不过期
					context['email'] = email
					context['code'] = code
					return render(request, 'users/resetpwd.html', context=context)

				else:
					return render(request, 'users/url_failed.html')

		else:
			return render(request, 'users/url_failed.html')


# 同时共用一个html
# 由于ResetPwdView的get所设的url中有`reset_code`参数，所以post不能共用一个url
class ModifyPwdView(View):
	def post(self, request):
		context = {}

		modifypwd_form = ModifyPwdForm(request.POST)
		context['modifypwd_form'] = modifypwd_form
		if modifypwd_form.is_valid():
			email = request.POST.get('email', '')
			code = request.POST.get('code', '')
			pass_word = request.POST.get('password', '')
			pass_word2 = request.POST.get('password2', '')
			if pass_word == pass_word2:
				obj_user = UserProfile.objects.get(email=email)
				obj_user.password = make_password(pass_word, salt=obj_user)
				obj_user.save()
				obj_email = EmailVerifyRecord.objects.get(code=code)
				obj_email.expire_status = 0
				obj_email.save()
				return render(request, 'users/login.html', context=context)

			else:
				context['msg'] = '两次输入的密码不一致'
				return render(request, 'users/resetpwd.html', context=context)

		else:
			email = request.POST.get('email', '')  # 不是输入的，是传入的，所以此处不能省
			context['email'] = email
			return render(request, 'users/resetpwd.html', context=context)


'''
def loginView(request):
	"""登录视图"""
	context = {}

	if request.method == 'POST':
		user_name = request.POST.get('username', '')
		pass_word = request.POST.get('password', '')
		user = authenticate(username=user_name, password=pass_word)
		if user is not None:
			login(request, user)
			obj_query = UserProfile.objects.filter(Q(username=user_name)|Q(email=user_name)).values('nickname', 'image')
			context['obj_query'] = obj_query
			return render(request, 'index.html', context=context)

		else:
			return render(request, 'users/login.html', context=context)

	elif request.method == 'GET':
		return render(request, 'users/login.html', context=context)
'''


class LoginView(View):
	"""登录视图---基于类的方法"""
	def get(self, request):
		context = {}

		return render(request, 'users/login.html', context=context)

	def post(self, request):
		context = {}

		login_form = LoginForm(request.POST)  # 传入字段参数则进行验证<传入的参数是一个dict（即传入需验证的字段）>

		# 若报错，`login_form`则可将原有输入字段传给跳转的html，即保留原有的输入(在html字段中已有给定`value`值的情况下)
		# 若验证错误，`login_form`则可将`_errors`传入html
		context['login_form'] = login_form
		if login_form.is_valid():  # is_valid()，检查login_form中返回的`_errors`是否为空，为空则验证通过，否则验证出错
			user_name = request.POST.get('username', '')
			pass_word = request.POST.get('password', '')
			user = authenticate(username=user_name, password=pass_word)
			context['user_name'] = user_name
			if user is not None:
				if user.is_active:  # 用户已激活
					login(request, user)
					obj_query = UserProfile.objects.filter(Q(username=user_name) | Q(email=user_name)).values('nickname',
																										  'image')
					context['obj_query'] = obj_query
					return render(request, 'index.html', context=context)

				else:  # 用户未激活
					context['msg'] = '用户未激活'
					return render(request, 'users/login.html', context=context)

			else:
				context['msg'] = '用户名或密码错误'
				return render(request, 'users/login.html', context=context)

		else:
			return render(request, 'users/login.html', context=context)


class LogoutView(View):
	def get(self, request):
		context = {}

		logout(request)
		return render(request, 'users/login.html', context=context)
